import datetime
import re

import jwt
from django.http import JsonResponse
from rest_framework.decorators import api_view, authentication_classes
from rest_framework.generics import CreateAPIView
from rest_framework.views import APIView
from rest_framework.response import Response
from django_redis import get_redis_connection
from django.http import HttpRequest, JsonResponse, HttpResponse

from app_user.auths import AllowPostAuthentication, AllowGetAuthentication, UserAuthentication
from app_user.captcha import Captcha
from app_user.serializers import RegisterCreateSerializer
from app_user.utils import random_captcha_text, gen_mobile_code, send_sms_by_luosimao, to_md5_hex
from xuanba_model.models import Users
from xuanba_setting.settings import SECRET_KEY

TEL_PATTERN = re.compile(r'1[356789]\d{9}')


def test(request):
    print(request)
    return JsonResponse({'code': 200, 'data': '测试成功'})


@api_view(['GET'])
@authentication_classes((AllowGetAuthentication, ))
def username_count(request, username):
    # 判断用户名是否存在
    count = Users.objects.filter(user_name=username).count()
    data = {
        'count': count,
        'username': username,
    }
    return Response(data)


@api_view(['GET'])
@authentication_classes((AllowGetAuthentication, ))
def tel_count(request, tel):
    if TEL_PATTERN.fullmatch(tel):
        count = Users.objects.filter(tel=tel).count()
        context = {
            'error': 2001,
            'count': count,
            'tel': tel,
        }
    else:
        context = {
            'error': 2002,
            'tel': tel,
            'count': -1,
        }
    return Response(context)


@api_view(['GET'])
@authentication_classes((AllowGetAuthentication, ))
def send_code_by_sms(request, tel):
    redis_conn = get_redis_connection('code')
    if redis_conn.get('sms_flag_%s' % tel):
        return Response({'message': '60s内请勿重复发送短信'})
    sms_code = gen_mobile_code()
    print(sms_code)
    message = f'您的短信验证码是{sms_code}，打死也不能告诉别人哟！【Python小课】'
    result = send_sms_by_luosimao(tel, message=message)
    if result['error'] == 0:
        redis_conn.setex('sms_%s' % tel, 100000, sms_code)
        redis_conn.setex('sms_flag_%s' % tel, 60, 1)
        data = {'code': 10001, 'msg': '短信验证码发送成功'}
    else:
        data = {'code': 10004, 'msg': '短信服务暂时无法使用'}
    return Response(data)


@api_view(['GET'])
@authentication_classes((AllowGetAuthentication, ))
def get_captcha(request, username):
    captcha_text = random_captcha_text()
    image_data = Captcha.instance().generate(captcha_text)
    redis_conn = get_redis_connection('code')
    redis_conn.setex('img_%s' % username, 1000000, captcha_text)
    print(captcha_text)
    return HttpResponse(image_data, content_type='image/png')


class RegisterCreateView(CreateAPIView):
    serializer_class = RegisterCreateSerializer
    authentication_classes = (AllowPostAuthentication, )


@api_view(['POST'])
@authentication_classes((AllowPostAuthentication, ))
def login_by_pwd(request):
    login_count = request.data.get('login_count')
    password = to_md5_hex(request.data.get('password'))
    if login_count and password:
        if TEL_PATTERN.fullmatch(login_count):
            user = Users.objects.filter(tel=login_count, password=password).first()
        else:
            user = Users.objects.filter(user_name=login_count, password=password).first()
        if user:
            payload = {
                'exp' : datetime.datetime.utcnow() + datetime.timedelta(days=1),
                'data' : {'userid': user.user_id}
            }
            token = jwt.encode(payload, SECRET_KEY, algorithm='HS256').decode()
            data = {'code': 20001, 'token': token, 'hint': '登陆成功'}
        else:
            data = {'code': 20002, 'hint': '用户名或密码错误'}
    else:
        data = {'code': 20003, 'hint': '请输入有效的登录信息'}
    return Response(data)


@api_view(['POST'])
@authentication_classes((AllowPostAuthentication, ))
def login_by_sms(request):
    tel = request.data.get('tel')
    sms_code = request.data.get('sms_code')
    if tel and sms_code:
        redis_conn = get_redis_connection("code")
        redis_sms_code = redis_conn.get("sms_%s" % tel)
        print(redis_sms_code)
        print(sms_code)
        if redis_sms_code.decode() == sms_code:
            user = Users.objects.filter(tel=tel).first()
            if user:
                payload = {
                    'exp': datetime.datetime.utcnow() + datetime.timedelta(days=1),
                    'data': {'user_id': user.user_id}
                }
                token = jwt.encode(payload, SECRET_KEY, algorithm='HS256').decode()
                data = {'code': 20001, 'token': token, 'hint': '登陆成功'}
            else:
                data = {'code': 20002, 'hint': '该手机号不存在'}
        else:
            data = {'code': 20003, 'hint': '手机验证码错误'}
    else:
        data = {'code': 2004, 'hint': '请输入有效的登录信息'}
    return Response(data)


